﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml;
using NUnit.Framework;
using Send2Sharepoint.Copy;
using Send2Sharepoint.Repository;

namespace Send2SharepointTests
{
    [TestFixture]
    public class RepositoryShould
    {
        private const string DocumentLibraryName = "Library";
        private const string UserName = "administrator";
        private const string Password = "kavithaarun";
        private const string SharepointUrl = "http://sapdss:1000";
        private const string FileName = "sample.txt";
        private static readonly string FileUrl = new Uri(new Uri(SharepointUrl), DocumentLibraryName + "/" + FileName).ToString();

        [TestFixtureSetUp]
        public void Init()
        {
            var repository = new Repository(UserName, Password, SharepointUrl);
            repository.CreateDocumentLibrary(DocumentLibraryName,"Description ...",101);
            repository.AddFields(DocumentLibraryName, CreateTextBox(10, "TRUE", "Name", "Name"));
            repository.AddFields(DocumentLibraryName, CreateTextArea(10, "FALSE", "Address", "Address"));
            repository.AddFields(DocumentLibraryName, CreateNumber("FALSE", "Age", "Age","FALSE",10,90));
            repository.AddFields(DocumentLibraryName, CreateComboBox("TRUE", "TRUE", "Country", "Country",new[]{"UK","India","USA"},"UK"));
            repository.AddFields(DocumentLibraryName, CreateRadioButtons("Sex", "Sex", new[] { "Male", "Female", "N/A" }, "Male"));
            repository.AddFields(DocumentLibraryName, CreateCheckBoxes("Skills", "Skills", new[] { "C#", "Biztalk", "Sharepoint" }, "Sharepoint"));
        }

        [TestFixtureTearDown]
        public void Dispose()
        {
            var repository = new Repository(UserName, Password, SharepointUrl);
            repository.DeleteList(DocumentLibraryName);

        }

        [Test]
        public void WillUploadADocument()
        {
            const string fileData = "sample text file";
            var file = Encoding.UTF8.GetBytes(fileData);
            var repository = new Repository(UserName, Password, SharepointUrl);
            var metadata = new List<FieldInformation>
                               {
                                   new FieldInformation
                                       {
                                            Value = "Sample doc",
                                            DisplayName = "Title",
                                            Type = FieldType.Text,
                                            InternalName = "Title"
                                       }
                               };
            repository.UploadFile2007(FileUrl,file,metadata);
            var wc = new WebClient {Credentials = new NetworkCredential(UserName, Password)};
            byte[] data = wc.DownloadData(FileUrl);
            Assert.That(Encoding.ASCII.GetString(data), Is.EqualTo(fileData));
        }

        [Test]
        public void WillReturnAllUserDefinedColumns()
        {
            var repository = new Repository(UserName, Password, SharepointUrl);
            var elements = repository.GetColumnsMetaData(DocumentLibraryName);
            Assert.That(elements.Count(),Is.EqualTo(7));
        }

        [Test]
        public void WillReturnRequiredColumns()
        {
            var repository = new Repository(UserName, Password, SharepointUrl);
            var elements = repository.GetColumnsMetaData(DocumentLibraryName).ToArray();
            Assert.That(elements[1].Attributes["Required"], Is.Not.Null);
            Assert.That(elements[1].Attributes["Required"].Value, Is.EqualTo("TRUE"));
        }

        private static XmlNode CreateTextBox(int maxLength, string required, string name, string displayName)
        {
            var doc = new XmlDocument();
            var ndNewFields = doc.CreateNode(XmlNodeType.Element,"Fields","");
            ndNewFields.InnerXml = "<Method ID='1'><Field Type='Text' MaxLength='" + maxLength + "' Required='" + required + "' Name='" + name + "' DisplayName='" + displayName + "'/></Method>";
            return ndNewFields;
        }

        private static XmlNode CreateTextArea(int maxLength, string required, string name, string displayName)
        {
            var doc = new XmlDocument();
            var ndNewFields = doc.CreateNode(XmlNodeType.Element, "Fields", "");
            ndNewFields.InnerXml = "<Method ID='1'><Field Type='Note' MaxLength='" + maxLength + "' Required='" + required + "' Name='" + name + "' DisplayName='" + displayName + "'/></Method>";
            return ndNewFields;
        }

        private static XmlNode CreateNumber(string required, string name, string displayName, string percentage,double min, double max)
        {
            var doc = new XmlDocument();
            var ndNewFields = doc.CreateNode(XmlNodeType.Element, "Fields", "");
            ndNewFields.InnerXml = "<Method ID='1'><Field Type='Number' Min='" + min + "' Max='" + max + "' Required='" + required + "' Name='" + name + "' DisplayName='" + displayName + "' Percentage='" + percentage + "'/></Method>";
            return ndNewFields;
        }

        private static XmlNode CreateComboBox(string fillInChoice, string required, string name, string displayName,IEnumerable<string> choices, string defaultValue)
        {
            var doc = new XmlDocument();
            var ndNewFields = doc.CreateNode(XmlNodeType.Element, "Fields", "");
            var choicesString = new StringBuilder(); 
            foreach (var choice in choices)
            {
                choicesString.Append("<CHOICE>" + choice + "</CHOICE>");
            }
            ndNewFields.InnerXml = "<Method ID='1'>"
                                     + "<Field Type='Choice' Format='Dropdown' Required='" + required + "' Name='" + name + "' DisplayName='" + displayName + "' FillInChoice='" + fillInChoice + "'>"
                                     + "<Default>" + defaultValue + "</Default>"
                                     + "<CHOICES>"
                                     + choicesString
                                     + "</CHOICES>"
                                     + "</Field>"
                                     + "</Method>";
            return ndNewFields;
        }

        private static XmlNode CreateRadioButtons(string name, string displayName, IEnumerable<string> choices, string defaultValue)
        {
            var doc = new XmlDocument();
            var ndNewFields = doc.CreateNode(XmlNodeType.Element, "Fields", "");
            var choicesString = new StringBuilder();
            foreach (var choice in choices)
            {
                choicesString.Append("<CHOICE>" + choice + "</CHOICE>");
            }
            ndNewFields.InnerXml = "<Method ID='1'>"
                                     + "<Field Type='Choice' Format='RadioButtons' Name='" + name + "' DisplayName='" + displayName + "'>"
                                     + "<Default>" + defaultValue + "</Default>"
                                     + "<CHOICES>"
                                     + choicesString
                                     + "</CHOICES>"
                                     + "</Field>"
                                     + "</Method>";
            return ndNewFields;
        }

        private static XmlNode CreateCheckBoxes(string name, string displayName, IEnumerable<string> choices, string defaultValue)
        {
            var doc = new XmlDocument();
            var ndNewFields = doc.CreateNode(XmlNodeType.Element, "Fields", "");
            var choicesString = new StringBuilder();
            foreach (var choice in choices)
            {
                choicesString.Append("<CHOICE>" + choice + "</CHOICE>");
            }
            ndNewFields.InnerXml = "<Method ID='1'>"
                                   + "<Field Type='MultiChoice' Name='" + name + "' DisplayName='" + displayName + "'>"
                                   + "<Default>" + defaultValue + "</Default>"
                                   + "<CHOICES>"
                                   + choicesString
                                   + "</CHOICES>"
                                   + "</Field>"
                                   + "</Method>";
            return ndNewFields;
        }
    }
}
